package com.lucifer.cloud.boot.blog.service.impl;

import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lucifer.cloud.boot.blog.domin.bo.Blog;
import com.lucifer.cloud.boot.blog.domin.type.BlogConstant;
import com.lucifer.cloud.boot.blog.domin.type.BlogStatusType;
import com.lucifer.cloud.boot.blog.domin.type.BlogType;
import com.lucifer.cloud.boot.blog.domin.bo.Exhibition;
import com.lucifer.cloud.boot.blog.domin.bo.Follow;
import com.lucifer.cloud.boot.blog.domin.bo.Likes;
import com.lucifer.cloud.boot.blog.domin.bo.Star;
import com.lucifer.cloud.boot.blog.domin.bo.User;
import com.lucifer.cloud.boot.blog.domin.dto.user.UserConverter;
import com.lucifer.cloud.boot.blog.domin.dto.user.UserDetail;
import com.lucifer.cloud.boot.blog.domin.dto.user.UserDetailDto;
import com.lucifer.cloud.boot.blog.domin.dto.user.UserInfo;
import com.lucifer.cloud.boot.blog.domin.dto.user.UserInfoDto;
import com.lucifer.cloud.boot.blog.domin.dto.user.UserReq;
import com.lucifer.cloud.boot.blog.mapper.ExhibitionMapper;
import com.lucifer.cloud.boot.blog.mapper.UserMapper;
import com.lucifer.cloud.boot.blog.service.BlogService;
import com.lucifer.cloud.boot.blog.service.FollowService;
import com.lucifer.cloud.boot.blog.service.LikesService;
import com.lucifer.cloud.boot.blog.service.StarService;
import com.lucifer.cloud.boot.blog.service.UserService;
import com.lucifer.cloud.boot.blog.config.UserSystem;
import com.lucifer.cloud.commons.model.Result;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * @author lucifer
 * @date 2023/12/21 15:24
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private BlogService blogService;

    @Resource
    private ExhibitionMapper exhibitionMapper;

    @Resource
    private LikesService likesService;

    @Resource
    private StarService starService;

    @Resource
    private FollowService followService;
    @Resource
    private UserSystem userSystem;

    @Override
    public UserInfoDto userInfo(HttpServletRequest request, Long _t) {
        Long userId = userSystem.userId(request);
        User user = getById(userId);
        UserInfo user_info = UserConverter.convertInfo(user);

        List<Blog> blogList = blogService.list(Wrappers.lambdaQuery(Blog.class)
                .eq(Blog::getUser_id, userId)
                .eq(Blog::getStatus,BlogStatusType.OPEN.getIndex())
        );

        List<Follow> followList =  Lists.newArrayList();

//        List<Follow> followList = followService.list(Wrappers.lambdaQuery(Follow.class)
//                .eq(Follow::getFollow_user_id, userId)
//                .eq(Follow::getFollow_type,Boolean.TRUE)
//        );

        List<Likes> likesList = likesService.list(Wrappers.lambdaQuery(Likes.class)
                .eq(Likes::getUser_id, userId)
                .eq(Likes::getType, BlogType.BLOG.getIndex())
                .eq(Likes::getLikes_type,Boolean.TRUE)
        );
        List<Star> starList = starService.list(Wrappers.lambdaQuery(Star.class)
                .eq(Star::getUser_id, userId)
                .eq(Star::getType, BlogType.BLOG.getIndex())
                .eq(Star::getStar_type,Boolean.TRUE)
        );
        UserDetail user_detail = UserConverter.convertBlog2Detail(blogList,followList,likesList,starList);
        UserInfoDto userInfoDto = UserInfoDto.builder().user_info(user_info).user_detail(user_detail).build();
        return userInfoDto;
    }

    @Override
    public Result userUpdate(UserReq userReq) {
        if(Objects.isNull(userReq.getUid())){
            return Result.error(HttpStatus.UNAUTHORIZED.value(), BlogConstant.NOT_LOGIN);
        }
        boolean update = update(Wrappers.lambdaUpdate(User.class)
                .set(User::getUpdated_at, LocalDateTime.now())
                .set(StringUtils.isNotBlank(userReq.getAvatar_url()), User::getAvatar_url, userReq.getAvatar_url())
                .set(Objects.nonNull(userReq.getGender()), User::getGender, userReq.getGender())
                .set(StringUtils.isNotBlank(userReq.getGit_hub()), User::getGit_hub, userReq.getGit_hub())
                .set(StringUtils.isNotBlank(userReq.getMotto()), User::getMotto, userReq.getMotto())
                .set(StringUtils.isNotBlank(userReq.getQq()), User::getQq, userReq.getQq())
                .set(Objects.nonNull(userReq.getTel()), User::getTel, userReq.getTel())
                .set(StringUtils.isNotBlank(userReq.getUsername()), User::getUsername, userReq.getUsername())
                .set(StringUtils.isNotBlank(userReq.getWechat()), User::getWechat, userReq.getWechat())
                .set(StringUtils.isNotBlank(userReq.getBackground_image()), User::getBackground_image, userReq.getBackground_image())
                .eq(User::getUid, userReq.getUid())
        );
        return Result.success(update);
    }

    @Override
    public Boolean passwordUpdate(HttpServletRequest request,String password) {
        Long userId = userSystem.userId(request);
        User user = new User();
        user.setId(userId.longValue());
        user.setUpdated_at(LocalDateTime.now());
        user.setPassword(password);
        return  updateById(user);
    }

    @Override
    public UserDetailDto userDetail(HttpServletRequest request, String uid, Integer page, Integer limit, Integer type) {
        Long userId = Long.valueOf(uid);
        User user = getById(userId);
        UserInfo user_info = UserConverter.convertInfo(user);

        List<Likes> likesList = likesService.list(Wrappers.lambdaQuery(Likes.class)
                .eq(Likes::getUser_id, userId)
                .eq(Likes::getType, BlogType.IMAGE.getIndex())
                .eq(Likes::getLikes_type,Boolean.TRUE)
        );

        List<String> likes_ids = Optional.ofNullable(likesList).orElse(Lists.newArrayList())
                .stream().map(Likes::getLikes_id)
                .map(String::valueOf)
                .collect(Collectors.toList());

        Page<Exhibition> rowPage = new Page<>(page, limit);
        Page<Exhibition> exhibitionPage = exhibitionMapper.selectPage(rowPage,Wrappers.lambdaQuery(Exhibition.class)
                .eq(!Objects.equals(BlogStatusType.APPROVE.getIndex(), type),Exhibition::getUser_id,userId)
                        .eq(BlogStatusType.UPLOAD.getIndex() == type || BlogStatusType.OPEN.getIndex() == type,
                                Exhibition::getStatus,type)
                        .in(BlogStatusType.APPROVE.getIndex() == type,Exhibition::getUid,likes_ids.size()== 0 ? Lists.newArrayList(""):likes_ids)
                //.eq(StringUtils.isNotBlank(uid),Exhibition::getUid,uid)
        );
        List<Exhibition> exhibitionList = exhibitionPage.getRecords();
        long count = exhibitionPage.getTotal();


        List<Star> starList = starService.list(Wrappers.lambdaQuery(Star.class)
                .eq(Star::getUser_id, userId)
                .eq(Star::getType, BlogType.IMAGE.getIndex())
                .eq(Star::getStar_type,Boolean.TRUE)
        );

        List<Follow> followList = followService.list(Wrappers.lambdaQuery(Follow.class)
                .eq(StringUtils.isNotBlank(uid), Follow::getFollow_user_id, uid)
                .eq(Follow::getFollow_type,Boolean.TRUE)
        );

        return UserConverter.convert2UserDetailDto(user_info,exhibitionList,count,likesList,starList,followList);
    }


}
